const express = require("express");
const https = require("https");
const jwt = require("jsonwebtoken");
const { usermodel } = require("../db/jjx"); // 引用数据库
const { log } = require("console");
const axios = require("axios");

const router = express.Router();

// 测试连接接口
router.get("/test", (req, res) => {
  res.json({
    success: true,
    message: "连接成功",
    timestamp: new Date().toISOString(),
    server: "cosmetic-surgery-backend",
  });
});

// 微信小程序配置 - 重要：请替换为你的实际配置
const WECHAT_CONFIG = {
  appId: "wx48ffd98350d13a57", // 微信小程序AppID
  appSecret: "31de965c2638b38471a8198e6e257e16", // 微信小程序AppSecret
  templateId: "xHtBOzfkOpgu36ZXRE78kQha3IsQCbZ07AL87mMHQpA", // 订阅消息模板ID
  jwtSecret: "cosmetic_surgery_jwt_secret_2024_32chars", // JWT签名密钥（建议使用32位以上随机字符串）

  // 订阅消息模板字段配置 - 根据微信公众平台的实际模板字段调整
  templateFields: {
    // 根据模板实际字段：验证码{{number3.DATA}}，有效期{{thing4.DATA}}，备注{{thing5.DATA}}
    verifyCode: "number3", // 验证码字段 - {{number3.DATA}}
    validTime: "thing4", // 有效期字段 - {{thing4.DATA}}
    remark: "thing5", // 备注字段 - {{thing5.DATA}}
  },
};

// ==================== 微信订阅消息服务 ====================

// access_token缓存
let wechatAccessToken = null;
let tokenExpireTime = 0;

/**
 * 获取微信access_token
 * @returns {Promise<string>} access_token
 */
async function getWechatAccessToken() {
  try {
    // 检查缓存的token是否还有效（提前5分钟过期）
    const now = Date.now();
    if (wechatAccessToken && now < tokenExpireTime - 5 * 60 * 1000) {
      return wechatAccessToken;
    }

    if (
      !WECHAT_CONFIG.appId ||
      !WECHAT_CONFIG.appSecret ||
      WECHAT_CONFIG.appId === "请在这里填入您的AppID" ||
      WECHAT_CONFIG.appSecret === "请在这里填入您的AppSecret"
    ) {
      throw new Error("微信AppID或AppSecret未配置");
    }

    console.log("🔑 获取微信access_token...");

    const response = await axios.get(
      "https://api.weixin.qq.com/cgi-bin/token",
      {
        params: {
          grant_type: "client_credential",
          appid: WECHAT_CONFIG.appId,
          secret: WECHAT_CONFIG.appSecret,
        },
        timeout: 10000,
      }
    );

    const result = response.data;

    if (result.errcode) {
      throw new Error(`微信API错误 ${result.errcode}: ${result.errmsg}`);
    }

    // 缓存token
    wechatAccessToken = result.access_token;
    tokenExpireTime = now + (result.expires_in || 7200) * 1000;

    console.log("✅ 微信access_token获取成功");
    return wechatAccessToken;
  } catch (error) {
    console.error("❌ 获取微信access_token失败:", error.message);
    throw error;
  }
}

/**
 * 发送订阅消息
 * @param {string} openid - 用户openid
 * @param {string} code - 验证码
 * @param {string} phone - 手机号（用于日志）
 * @returns {Promise<Object>} 发送结果
 */
async function sendWechatVerificationMessage(openid, code, phone) {
  try {
    if (!openid) {
      throw new Error("用户openid不能为空");
    }

    // 验证openid格式（微信openid通常是28位字符串）
    if (openid.length !== 28 || openid.startsWith("mock_")) {
      throw new Error("无效的openid格式");
    }

    console.log(`📱 准备发送微信订阅消息: ${phone} -> ${code}`);

    const accessToken = await getWechatAccessToken();

    // 构造消息数据 - 使用配置化的微信模板字段
    const messageData = {
      touser: openid,
      template_id: WECHAT_CONFIG.templateId,
      data: {},
    };

    // 使用配置化的字段名，根据模板实际字段配置
    const fields = WECHAT_CONFIG.templateFields;
    messageData.data[fields.verifyCode] = { value: code };
    messageData.data[fields.validTime] = { value: "5分钟内有效" };
    messageData.data[fields.remark] = { value: "请勿向他人泄露验证码" };

    console.log("📤 发送的消息数据:", JSON.stringify(messageData, null, 2));

    const response = await axios.post(
      `https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token=${accessToken}`,
      messageData,
      {
        headers: {
          "Content-Type": "application/json",
        },
        timeout: 10000,
      }
    );

    const result = response.data;

    if (result.errcode === 0) {
      console.log(`✅ 微信订阅消息发送成功: ${phone}`);
      return {
        success: true,
        message: "微信通知发送成功",
        data: result,
      };
    } else {
      throw new Error(`微信消息发送失败 ${result.errcode}: ${result.errmsg}`);
    }
  } catch (error) {
    console.error("❌ 微信订阅消息发送失败:", error.message);

    // 根据错误类型提供更友好的错误信息
    let userMessage = "微信通知发送失败";
    if (error.message.includes("用户拒绝接受消息")) {
      userMessage = "用户未授权接收通知";
    } else if (error.message.includes("模板参数格式错误")) {
      userMessage = "消息模板配置错误";
    } else if (error.message.includes("access_token")) {
      userMessage = "微信服务连接失败";
    }

    throw new Error(userMessage);
  }
}

/**
 * 检查微信配置状态
 * @returns {Object} 配置状态
 */
function getWechatConfigStatus() {
  const hasAppId = !!(
    WECHAT_CONFIG.appId && WECHAT_CONFIG.appId !== "请在这里填入您的AppID"
  );
  const hasAppSecret = !!(
    WECHAT_CONFIG.appSecret &&
    WECHAT_CONFIG.appSecret !== "请在这里填入您的AppSecret"
  );
  const hasTemplateId = !!WECHAT_CONFIG.templateId;

  return {
    hasAppId,
    hasAppSecret,
    hasTemplateId,
    isConfigured: hasAppId && hasAppSecret && hasTemplateId,
  };
}

/*
 * 配置说明：
 * 1. 登录微信公众平台 (https://mp.weixin.qq.com/)
 * 2. 进入小程序管理后台
 * 3. 在"开发" -> "开发管理" -> "开发设置"中获取AppID和AppSecret
 * 4. 将上面的配置替换为你的实际值
 * 5. JWT密钥建议使用随机生成的32位以上字符串
 */

// 微信登录接口
router.post("/wechat-login", async (req, res) => {
  try {
    const { code, agreeProtocol, userInfo } = req.body;

    // 验证必要参数
    if (!code) {
      return res.status(400).json({
        success: false,
        message: "缺少微信登录码",
      });
    }

    if (!agreeProtocol) {
      return res.status(400).json({
        success: false,
        message: "请先同意用户协议",
      });
    }

    // 调用微信API获取用户信息
    const wechatUserInfo = await getWechatUserInfo(code);

    if (!wechatUserInfo) {
      console.error("微信API调用失败，返回null");
      return res.status(400).json({
        success: false,
        message: "微信登录失败，请重试",
        debug: "微信API调用失败",
      });
    }

    // 查找或创建用户
    let user = await usermodel.findOne({ openid: wechatUserInfo.openid });

    if (!user) {
      // 创建新用户
      user = new usermodel({
        openid: wechatUserInfo.openid,
        unionid: wechatUserInfo.unionid,
        session_key: wechatUserInfo.session_key,
        agreeProtocol: true,
        createdAt: new Date(),
        lastLoginAt: new Date(),
        // 添加用户信息字段
        nickname: userInfo?.nickName || "",
        avatarUrl: userInfo?.avatarUrl || "",
      });
      await user.save();
    } else {
      // 更新现有用户的登录时间、session_key和用户信息
      user.session_key = wechatUserInfo.session_key;
      user.lastLoginAt = new Date();
      if (!user.agreeProtocol) {
        user.agreeProtocol = true;
      }
      // 更新用户信息（如果提供了的话）
      if (userInfo) {
        user.nickname = userInfo.nickName || user.nickname;
        user.avatarUrl = userInfo.avatarUrl || user.avatarUrl;
      }
      await user.save();
    }

    // 生成JWT token
    const token = jwt.sign(
      {
        userId: user._id,
        openid: user.openid,
      },
      WECHAT_CONFIG.jwtSecret,
      { expiresIn: "7d" } // token有效期7天
    );

    res.json({
      success: true,
      message: "登录成功",
      token: token,
      userInfo: {
        id: user._id,
        openid: user.openid,
        nickname: user.nickname,
        avatarUrl: user.avatarUrl,
        createdAt: user.createdAt,
        lastLoginAt: user.lastLoginAt,
      },
    });
  } catch (error) {
    console.error("微信登录错误:", error);
    res.status(500).json({
      success: false,
      message: "服务器内部错误",
    });
  }
});

// 调用微信API获取用户信息
function getWechatUserInfo(code) {
  return new Promise((resolve, reject) => {
    const url = `https://api.weixin.qq.com/sns/jscode2session?appid=${WECHAT_CONFIG.appId}&secret=${WECHAT_CONFIG.appSecret}&js_code=${code}&grant_type=authorization_code`;

    https
      .get(url, (response) => {
        let data = "";

        response.on("data", (chunk) => {
          data += chunk;
        });

        response.on("end", () => {
          try {
            const result = JSON.parse(data);

            if (result.errcode) {
              console.error("微信API返回错误:", result);
              console.error(
                `错误码: ${result.errcode}, 错误信息: ${result.errmsg}`
              );
              resolve(null);
            } else if (result.openid) {
              resolve({
                openid: result.openid,
                session_key: result.session_key,
                unionid: result.unionid,
              });
            } else {
              console.error("微信API响应格式异常，缺少openid:", result);
              resolve(null);
            }
          } catch (error) {
            console.error("解析微信API响应失败:", error);
            console.error("原始响应数据:", data);
            resolve(null);
          }
        });
      })
      .on("error", (error) => {
        console.error("调用微信API网络失败:", error);
        resolve(null);
      });
  });
}

// 验证token中间件
function authenticateToken(req, res, next) {
  const authHeader = req.headers["authorization"];
  const token = authHeader && authHeader.split(" ")[1]; // Bearer TOKEN

  if (!token) {
    return res.status(401).json({
      success: false,
      message: "访问被拒绝，缺少token",
    });
  }

  jwt.verify(token, WECHAT_CONFIG.jwtSecret, (err, user) => {
    if (err) {
      return res.status(403).json({
        success: false,
        message: "token无效或已过期",
      });
    }
    req.user = user;
    next();
  });
}

// 获取当前用户信息接口（需要登录）
router.get("/user-info", authenticateToken, async (req, res) => {
  try {
    const user = await usermodel.findById(req.user.userId);
    if (!user) {
      return res.status(404).json({
        success: false,
        message: "用户不存在",
      });
    }

    res.json({
      success: true,
      userInfo: {
        id: user._id,
        openid: user.openid,
        agreeProtocol: user.agreeProtocol,
        createdAt: user.createdAt,
        lastLoginAt: user.lastLoginAt,
      },
    });
  } catch (error) {
    console.error("获取用户信息错误:", error);
    res.status(500).json({
      success: false,
      message: "服务器内部错误",
    });
  }
});

// ==================== 手机号登录相关接口 ====================

// 临时存储验证码的Map（生产环境建议使用Redis）
const verificationCodes = new Map();

// 生成6位随机验证码
function generateVerificationCode() {
  return Math.floor(100000 + Math.random() * 900000).toString();
}

// 验证手机号格式
function validatePhoneNumber(phone) {
  const phoneRegex = /^1[3-9]\d{9}$/;
  return phoneRegex.test(phone);
}

// 发送短信验证码接口
router.post("/send-sms", async (req, res) => {
  try {
    const { phone, openid } = req.body;

    // 验证手机号格式
    if (!phone || !validatePhoneNumber(phone)) {
      return res.status(400).json({
        success: false,
        message: "请输入正确的手机号",
      });
    }

    // 检查发送频率限制（60秒内只能发送一次）
    const now = Date.now();
    const lastSentTime = verificationCodes.get(`time_${phone}`);
    if (lastSentTime && now - lastSentTime < 60000) {
      return res.status(429).json({
        success: false,
        message: "验证码发送过于频繁，请稍后再试",
      });
    }

    // 生成验证码
    const code = generateVerificationCode();

    // 存储验证码（5分钟有效期）
    verificationCodes.set(phone, code);
    verificationCodes.set(`time_${phone}`, now);

    // 设置验证码过期时间（5分钟后自动删除）
    setTimeout(() => {
      verificationCodes.delete(phone);
      verificationCodes.delete(`time_${phone}`);
    }, 5 * 60 * 1000);

    // 尝试发送微信订阅消息
    try {
      if (openid && getWechatConfigStatus().isConfigured) {
        console.log(`🔍 检查openid: ${openid} (长度: ${openid.length})`);

        // 发送微信订阅消息
        await sendWechatVerificationMessage(openid, code, phone);

        console.log(`✅ 微信订阅消息发送成功: ${phone}`);

        // 开发环境返回验证码便于测试
        const isDevelopment = process.env.NODE_ENV !== "production";

        res.json({
          success: true,
          message: "验证码已发送到微信通知",
          method: "wechat",
          ...(isDevelopment && { devCode: code }),
        });
      } else {
        // 没有openid或微信未配置，使用模拟模式
        throw new Error("微信服务未配置或用户未提供openid");
      }
    } catch (wechatError) {
      // 微信发送失败，降级到模拟模式
      console.log(`⚠️ 微信发送失败，使用模拟模式: ${wechatError.message}`);
      console.log(`📱 模拟发送验证码到 ${phone}: ${code}`);

      // 在开发环境中，将验证码返回给前端
      const isDevelopment = process.env.NODE_ENV !== "production";

      res.json({
        success: true,
        message: "验证码发送成功",
        method: "mock",
        // 开发环境下返回验证码便于测试
        ...(isDevelopment && { devCode: code }),
        // 开发环境显示降级原因
        ...(isDevelopment && { fallbackReason: wechatError.message }),
      });
    }
  } catch (error) {
    console.error("发送验证码错误:", error);
    res.status(500).json({
      success: false,
      message: "发送验证码失败，请重试",
    });
  }
});

// 手机号登录接口
router.post("/phone-login", async (req, res) => {
  try {
    const { phone, code, openid } = req.body;

    // 验证必要参数
    if (!phone || !code) {
      return res.status(400).json({
        success: false,
        message: "手机号和验证码不能为空",
      });
    }

    // 验证手机号格式
    if (!validatePhoneNumber(phone)) {
      return res.status(400).json({
        success: false,
        message: "请输入正确的手机号",
      });
    }

    // 验证验证码
    const storedCode = verificationCodes.get(phone);
    if (!storedCode) {
      return res.status(400).json({
        success: false,
        message: "验证码已过期，请重新获取",
      });
    }

    if (storedCode !== code) {
      return res.status(400).json({
        success: false,
        message: "验证码错误",
      });
    }

    // 验证码使用后立即删除
    verificationCodes.delete(phone);
    verificationCodes.delete(`time_${phone}`);

    // 智能查找或创建用户 - 优先通过openid关联已有用户
    let user = null;
    let userFound = false;
    let bindingType = "";

    // 1. 优先查找是否有相同openid的微信用户（需要绑定手机号）
    if (openid && openid !== "" && !openid.startsWith("mock_")) {
      user = await usermodel.findOne({ openid: openid });
      if (user) {
        console.log(`🔗 找到已有微信用户，绑定手机号: ${openid} -> ${phone}`);

        // 绑定手机号到已有微信用户
        user.phone = phone;
        user.phoneVerified = true;
        user.lastLoginAt = new Date();
        user.lastPhoneLoginAt = new Date();

        // 如果之前只是微信登录，现在更新登录类型
        if (user.loginType === "wechat") {
          user.loginType = "both"; // 支持微信和手机号双重登录
        }

        await user.save();
        userFound = true;
        bindingType = "wechat_to_phone";
      }
    }

    // 2. 如果没找到openid用户，查找是否有相同手机号的用户
    if (!userFound) {
      user = await usermodel.findByPhone(phone);
      if (user) {
        console.log(`📱 找到已有手机号用户: ${phone}`);

        // 如果有openid，也绑定到已有手机号用户
        if (openid && openid !== "" && !openid.startsWith("mock_")) {
          user.openid = openid;
          user.loginType = "both";
          console.log(`🔗 为手机号用户绑定openid: ${phone} -> ${openid}`);
        }

        // 更新登录时间
        await user.updatePhoneLogin();
        userFound = true;
        bindingType = "existing_phone";
      }
    }

    // 3. 都没找到，创建新用户
    if (!userFound) {
      console.log(`✨ 创建新用户: ${phone}`);

      // 如果有有效的openid，使用真实openid；否则生成伪openid
      const userOpenid =
        openid && openid !== "" && !openid.startsWith("mock_")
          ? openid
          : `phone_${phone}_${Date.now()}`;

      const loginType =
        openid && openid !== "" && !openid.startsWith("mock_")
          ? "both"
          : "phone";

      user = new usermodel({
        openid: userOpenid,
        phone: phone,
        phoneVerified: true,
        loginType: loginType,
        nickname: `用户${phone.slice(-4)}`, // 使用手机号后4位作为默认昵称
        agreeProtocol: true,
        createdAt: new Date(),
        lastLoginAt: new Date(),
        lastPhoneLoginAt: new Date(),
      });
      await user.save();
      bindingType = "new_user";
    }

    console.log(
      `✅ 手机号登录完成 - 类型: ${bindingType}, 用户ID: ${user._id}`
    );

    // 生成JWT token
    const token = jwt.sign(
      {
        userId: user._id,
        phone: user.phone,
        loginType: "phone",
      },
      WECHAT_CONFIG.jwtSecret,
      { expiresIn: "7d" } // token有效期7天
    );

    res.json({
      success: true,
      message: "登录成功",
      bindingType: bindingType, // 告诉前端绑定类型
      token: token,
      userInfo: {
        id: user._id,
        openid: user.openid,
        phone: user.phone,
        nickname: user.nickname,
        avatarUrl: user.avatarUrl || "",
        loginType: user.loginType,
        phoneVerified: user.phoneVerified,
        createdAt: user.createdAt,
        lastLoginAt: user.lastLoginAt,
        lastPhoneLoginAt: user.lastPhoneLoginAt,
      },
    });
  } catch (error) {
    console.error("手机号登录错误:", error);
    res.status(500).json({
      success: false,
      message: "登录失败，请重试",
    });
  }
});

// 绑定手机号到现有微信用户接口
router.post("/bind-phone", async (req, res) => {
  try {
    const { phone, code, userId } = req.body;

    // 验证必要参数
    if (!phone || !code || !userId) {
      return res.status(400).json({
        success: false,
        message: "缺少必要参数",
      });
    }

    // 验证手机号格式
    if (!validatePhoneNumber(phone)) {
      return res.status(400).json({
        success: false,
        message: "请输入正确的手机号",
      });
    }

    // 验证验证码
    const storedCode = verificationCodes.get(phone);
    if (!storedCode || storedCode !== code) {
      return res.status(400).json({
        success: false,
        message: "验证码错误或已过期",
      });
    }

    // 验证码使用后立即删除
    verificationCodes.delete(phone);
    verificationCodes.delete(`time_${phone}`);

    // 检查手机号是否已被其他用户使用
    const existingPhoneUser = await usermodel.findByPhone(phone);
    if (existingPhoneUser && existingPhoneUser._id.toString() !== userId) {
      return res.status(400).json({
        success: false,
        message: "该手机号已被其他用户绑定",
      });
    }

    // 查找要绑定的用户
    const user = await usermodel.findById(userId);
    if (!user) {
      return res.status(404).json({
        success: false,
        message: "用户不存在",
      });
    }

    // 绑定手机号
    user.phone = phone;
    user.phoneVerified = true;
    user.lastPhoneLoginAt = new Date();
    // loginType会通过pre('save')中间件自动更新为'both'
    await user.save();

    res.json({
      success: true,
      message: "手机号绑定成功",
      userInfo: {
        id: user._id,
        phone: user.phone,
        nickname: user.nickname,
        avatarUrl: user.avatarUrl,
        loginType: user.loginType,
        phoneVerified: user.phoneVerified,
      },
    });
  } catch (error) {
    console.error("绑定手机号错误:", error);
    res.status(500).json({
      success: false,
      message: "绑定失败，请重试",
    });
  }
});

module.exports = router;
